迷宫问题 非递归(java版)

一、简要
偶尔接触到迷宫问题发现挺有趣的,所以开始研究了一下。我觉得这个问题的关键是:

  • 怎么设计这个迷宫?
  • 怎么利用栈的特点来解决这个问题?
  • 在迷宫行走怎么更改迷宫的方向?
  • 怎么寻找迷宫路径?以及怎么才算找到迷宫路径?

二、思路

通过上面的问题关键,在脑中可以构造一个大体的思路:

  • 首先创建一个迷宫maze,对于迷宫可以采用mxn的一个二维数组来设计。
  • 创建一个mazenode节点类来控制二维数组中的每一个节点,另外还需要构造一个函数来设计每个节点(东、南、西、北)的可行性。
  • 为了保证在任何位置上都能沿原路退回,所以需要用一个后进先出的结构来保存从入口到当前位置的路径,因此在求迷宫通路的算法中要应用“栈”的思想,所以必须设计一个栈出来,用来存储“当前路径”,即“在搜索过程中某一时刻所在图中某个方块位置”。
  • 然后就可以开始寻找迷宫路径了,从迷宫的入口节点开始入栈,来寻找它下一个位置,如果当前位置的下个位置(东、南、西、北)可以走,那么就把当前位置的下个位置的行走状态改为不可以行走,把当前位置也改为不可以行走,(因为都是从那里走回来的不能再走回去了,不然就是一个死循环了),然后把下个位置节点入栈;继续寻找,如果遇见了死胡同,那么就开始出栈。如果入栈的节点的行列数和迷宫行列数相等,说明我们已经找到出口,可以跳出循环。或者另一种情况就是一直遇见死胡同,一直出栈,直到栈空,那就说明该迷宫没有路径。
  • 最后就可以出栈打印出迷宫路径。
  • 以上操作都是个人想法,如有错误还望指正。

三、java代码实现

//常数类方便操作

public class Constant {
public static final int WAY_NUMBER = 4;

    //表示路径可以行走
    public static final int WAY_ENABLE = 1;
    //表示路径不可以行走
    public static final int WAY_DISABLE = 0;

    //迷宫节点的四个方向
    public static final int WAY_EAST = 0;
    public static final int WAY_SOUTH = 1;
    public static final int WAY_WEST = 2;
    public static final int WAY_NORTH = 3;

}
//迷宫节点类
public class MazeNode {
    private int value;
    private int i;
    private int j;
    private int[] pathState;

    public MazeNode(int value, int i, int j){
        this.value = value;
        this.i = i;
        this.j = j;

        //初始化节点的四个方向的路径信息,都初始化成不能行走
        pathState = new int[Constant.WAY_NUMBER];
        for(int k=0; k<pathState.length; ++k){
            pathState[k] = Constant.WAY_DISABLE;
        }
    }
    //设置迷宫行走状态的构造函数
    public void setPathState(int path, int state){
        pathState[path]=state;
    }
    //获取迷宫行走状态的构造函数
    public int getPathState(int path){
        return pathState[path];
    }       
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }

    public int getRow() {
        return i;
    }

    public void setRow(int i) {
        this.i = i;
    }

    public int getCol() {
        return j;
    }
    public void setCol(int j) {
        this.j = j;
    }
}
import java.util.Arrays;
import java.util.Scanner;
//创建栈
class SqStack{
    private MazeNode[] stack;
    private int top;

    public SqStack(){
        top = 0;
        stack = new MazeNode[50];
    }

    //push要支持stack的内存增长操作,一次性增长2倍
    public void push(MazeNode node) {
    if(full())
        resize();
   this.stack[this.top++]=node;
   }
    public void pop() {
        if(empty())
         return ;
        this.top--;
    }
    public MazeNode top() {
        //return null;
        return this.stack[this.top-1];
    }
    public boolean empty() {
        //return false;
        return this.top == 0;
    }
    public boolean full() {
        //return false;
        return this.top == 0;
    }
    private void resize(){
        this.stack=Arrays.copyOf(this.stack, this.stack.length*2);
    } 
}


//构造迷宫类
class Maze{
    private int row;
    private int colum;
    private MazeNode[][] mazePath;//迷宫节点,二维数组
    private SqStack stack;
    public Maze(int row, int colum){
        this.row = row;
        this.colum = colum;
        mazePath = new MazeNode[this.row][this.colum];
        stack = new SqStack();
    }
    public void setPath(int i, int j, int value){
        mazePath[i][j] = new MazeNode(value, i, j);
    }    
    //该函数主要用来更改迷宫节点四个方向的行走状态
    public void adjustMazePath(){
        for(int i=0;i<this.row;i++){
            for(int j=0;j<this.colum;j++){
                //先调整最层路径
                if(mazePath[i][j].getValue()==0){
                  //东
                    if(j<this.colum-1&&mazePath[i][j+1].getValue()==0){
                        mazePath[i][j].setPathState(Constant.WAY_EAST,Constant.WAY_ENABLE);
                    }
                    //南
                    if(i<this.row-1&&mazePath[i+1][j].getValue()==0){
                        mazePath[i][j].setPathState(Constant.WAY_SOUTH,Constant.WAY_ENABLE);
                    }
                    //西
                    if(j>0&&mazePath[i][j-1].getValue()==0){
                        mazePath[i][j].setPathState(Constant.WAY_WEST,Constant.WAY_ENABLE);
                    }
                    //北
                    if(i>0&&mazePath[i-1][j].getValue()==0){
                        mazePath[i][j].setPathState(Constant.WAY_NORTH,Constant.WAY_ENABLE);
                    }
                }
            }
        }
}       
    //开始寻找迷宫路径
    public void findMazePath(){
        System.out.println("正在寻找迷宫路径。。。");
        this.stack.push(mazePath[0][0]);//入口传入栈
        int i=0,j=0;
        while(!this.stack.empty()){
        MazeNode top=this.stack.top();
        //如果top的行列数等于Maze的行列书,说明就已经找到出口
        if(i ==this.row-1&&j==this.colum-1){
            break;
        }
        //判断东
        if(top.getPathState(Constant.WAY_EAST)==Constant.WAY_ENABLE){
            mazePath[i][j].setPathState(Constant.WAY_EAST,  Constant.WAY_DISABLE);
            mazePath[i][j+1].setPathState(Constant.WAY_WEST,  Constant.WAY_DISABLE);
             this.stack.push(mazePath[i][j+1]);
             j++;
             continue;
        }
        //判断南
        if(top.getPathState(Constant.WAY_SOUTH)==Constant.WAY_ENABLE){
            mazePath[i][j].setPathState(Constant.WAY_SOUTH,  Constant.WAY_DISABLE);
            mazePath[i+1][j].setPathState(Constant.WAY_NORTH,  Constant.WAY_DISABLE);
            this.stack.push(mazePath[i+1][j]);
            i++;
            continue;
        }
        //判断西
        if(top.getPathState(Constant.WAY_WEST)==Constant.WAY_ENABLE){
            mazePath[i][j].setPathState(Constant.WAY_WEST,  Constant.WAY_DISABLE);
            mazePath[i][j-1].setPathState(Constant.WAY_EAST,  Constant.WAY_DISABLE);
             this.stack.push(mazePath[i][j-1]);
             j--;
             continue;
        }
        //判断北
        if(top.getPathState(Constant.WAY_NORTH)==Constant.WAY_ENABLE){
            mazePath[i][j].setPathState(Constant.WAY_NORTH,  Constant.WAY_DISABLE);
            mazePath[i-1][j].setPathState(Constant.WAY_SOUTH,  Constant.WAY_DISABLE);
            this.stack.push(mazePath[i-1][j]); 
            i--;
            continue;
        }
        this.stack.pop();
    }   
    if(this.stack.empty()){
        System.out.println("从左上角入口到右下角出口不存在有效路径   、、、、");
    }   
    }
    //打印最终的迷宫路径信息

    public void showMazePath(){

        while(!this.stack.empty()){
            MazeNode top=this.stack.top();
            int i=top.getRow();
            int j=top.getCol();
            mazePath[i][j].setValue(2);
            //System.out.printf("<%d,%d>->",this.stack.top().getRow(),this.stack.top().getCol()); 
            this.stack.pop();
        }
        System.out.println("路径已找到,输入如下(2代表行走的路径):");
        for(int i=0;i<this.row;i++){
            for(int j=0;j<this.colum;j++){
                System.out.print(mazePath[i][j].getValue()+" ");
            }
            System.out.println();
            }
    }

}
public class TestMazePathDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scan = new Scanner(System.in);

        System.out.print("请输入迷宫的行列数(m * n):");
        int row = scan.nextInt();
        int col = scan.nextInt();

        //maze现在代表的就是整个迷宫
        Maze maze = new Maze(row, col);

        System.out.println("请输入迷宫的路径:");
        for(int i=0; i<row; ++i){
            for(int j=0; j<col; ++j){
                int data = scan.nextInt();
                maze.setPath(i, j, data);
            }
        }

        //以上代码,就把整个迷宫路径的信息都设置到maze对象里面了
        //该函数主要用来更改迷宫节点四个方向的行走状态
        maze.adjustMazePath();
        //开始寻找迷宫路径
        maze.findMazePath();
        //打印最终的迷宫路径信息
        maze.showMazePath();
    }

}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值